import Aria2 from "aria2";
import ws from "ws";
import nodefetch from "node-fetch";
import { options as defaultOptions } from "./constat";
import { runEXE } from "../client"
// import { initializeDatabase } from "./data/db"

// import { app } from "electron"
// import path from "node:path"
// const userDataPath = app.getPath("userData");
// console.log("userDataPath----------------------------------->", userDataPath)
// const dbPath = path.join(userDataPath, 'download-tool.db');
// console.log("dbPath", dbPath)


// initializeDatabase();

// import { taskDatabase } from "@src/db"

// const TASK_DB = taskDatabase()


let WebSocketModule : any = null;
if (typeof window !== 'undefined') {
  // 在浏览器端
  WebSocketModule = window.WebSocket;
} else {
  // 在服务器端
  WebSocketModule = require('ws');
}


export class ARIA {
  private options: any;
  private aria:any
  protected EXE:any = null
  constructor(options?: any) {
    this.options = options || defaultOptions;
    this.aria = null;
  }

  async init() {
    this.EXE = await runEXE();
    this.aria = await new Aria2({
      WebSocket: WebSocketModule,
      fetch: nodefetch,
      ...this.options,
    });
    // this.open()
  }

  existAria() {
    return this.aria !== null;
  }

  async open() {
    if (this.existAria()) {
      this.aria
        .open()
        .then(() => {
          console.log("open");         
        })
        .catch((err) => console.log("open-error", err));
    }
  }

  events() {
    if (!this.existAria()) {
      // console.log("aria not exist", this.aria)
      return;
    }
    // emitted when the WebSocket is open.
    this.aria.on("open", () => {
      console.log("aria2 OPEN");
    });

    // emitted when the WebSocket is closed.
    this.aria.on("close", () => {
      console.log("aria2 CLOSE");
    });

    // emitted for every message sent.
    this.aria.on("output", (m) => {
      console.log("aria2 OUT", m);
    });

    // emitted for every message received.
    this.aria.on("input", (m) => {
      console.log("aria2 IN", m);
      // const gid = JSON.parse(m)?.params?[0]?.["gid"];
      console.log("type m",  m)
      const gid = m?.params ? m.params[0]["gid"] : null;
      console.log("gid", gid)
      gid && this.removeDownloadResult(gid)
    });
  }

  async close() {
    if (this.existAria()) {
      this.aria
        .close()
        .then(() => console.log("closed"))
        .catch((err) => console.log("close-error", err));
    }
  }

  async call(method, sources, opts = { dir: "/download" }) {
    if (this.existAria()) {
      const [guid] = this.aria.call(method, [sources], opts);
      return guid;
    }
  }

  async onNotification() {
    const notifications = await this.aria.listNotifications();
    notifications.forEach((notification) => {
      this.aria.on(notification, (params) => {
        console.log("listern aria2", notification, params);
      });
    });
  }

  async methods() {
    const methods = await this.aria.listMethods();
    methods?.forEach((method: any) => {
      this.aria.on(method, (...arg: any) => {
        console.log("listener method", method, arg)
      })
    });
  }
  // 根据gui删除一个任务
  protected async removeDownloadResult(guid: string){
    // const res = await this.EXE.removeDownloadResult(this.options.secret, guid )
    // console.log("delete task by guid", guid, res)
  }
  testInfo(){
    console.log("test info")
  }
}

export async function AriaEntity(options?:any) {
  const ENTIRY = options ? new ARIA(options) : new ARIA();
  await ENTIRY.init();
  await ENTIRY.open();
  ENTIRY.events();
  ENTIRY.methods();
  return ENTIRY;
}
